home *** CD-ROM | disk | FTP | other *** search
- {
- File: TranslateRotate.p
-
- Contains: Many people are uncomfortable with Apple's fixed-point data types,
- because they can't be used with normal operator arithmetic and
- because their representation is not easily readable (though it
- is easily converted to integer types). Here's something to show
- how simple it really is.
-
- TranslateRotate does two-dimensional translation and rotations
- in word-size coordinates, using fixed-point math. Each routine
- is passed info for a transform matrix which tells the routine what
- to do with the fPoint argument. Each routine then does its thing
- on its fPoint argument, returning the new fPoint position.
-
- The purpose of TranslateRotate is to provide a simple demo of the
- use of Fixed and Fract math in basic 2D transformations. The
- procedures sacrifice speed for clarity in their use of intermediate
- variables, etc.
-
- Fixed-point math has broad applications for speed-sensitive code,
- and is accurate enough for any screen graphics computations, if
- you are careful to perform your computations so as to minimize
- error propagation (do multiplications first, divisions last, for
- example). There are few reasons to use floating point unless you
- demand error smaller than 2 to the -16.
-
- For demonstration purposes, the two routines (one for rotation,
- one for translation) are called together from an MPW shell
- application. The application prompts you for x,y translation
- values and a rotation value in radians. It then calls a routine
- which first rotates and then translates the point. Type rotation
- = 999 to escape the program.
-
- Points are stored as fWords, which are of size WORD.
-
-
- Written by: Billster
-
- Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/16/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- }
-
-
- Program TranslateRotate;
-
- uses FixMath,ToolUtils;
-
- const
- FracToIntegerConversion = 1073741824; { Divide by this to turn Frac into truncated int }
- FixToIntegerConversion = 65536; { Divide by this to turn Fixed into truncated int }
-
- type
- fWord = integer; { This is the type for linear measurement hereafter }
-
- fPoint = record { This is the type for an arbitrary point }
- x : fWord;
- y : fWord;
- end;
-
- TransRot2D = record { This record holds all the information for the }
- x : fWord; { transformation or rotation of a point }
- y : fWord;
- rot : Fixed;
- end;
-
- TransRot3D = record { This would hold the information for the }
- x : fWord; { translation/rotation in the 3D case. }
- y : fWord; { The routines are not implemented in this }
- z : fWord; { sample, however. }
- rotXY : Fixed;
- rotYZ : Fixed;
- rotXZ : Fixed;
- end;
-
- var
- transformInput : transRot2D;
- fPtInput, fPtResult : fPoint;
- radians : real;
-
-
-
-
-
- { Routines for translation and rotation }
-
-
-
- Function Rotate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
- var
- sinRot, cosRot: Fract;
- begin
- sinRot := FracSin(theTransRot.rot);
- cosRot := FracCos(theTransRot.rot);
-
- Rotate2D.x := fWord( FracMul(cosRot,theFPoint.x) - FracMul(sinRot,theFPoint.y) );
- Rotate2D.y := fWord( FracMul(sinRot,theFPoint.x) + FracMul(cosRot,theFPoint.y) );
-
- { The above is a computation of:
-
- | cos(rot) -sin(rot) | | x |
- | | | |
- | sin(rot) cos(rot) | | y |
- }
- end;
-
-
-
- Function Translate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
- begin
- Translate2D.x := theFPoint.x + theTransRot.x;
- Translate2D.y := theFPoint.y + theTransRot.y;
-
- { The above is a computation of:
-
- | tranlate2D.x 0 | | x |
- | | | |
- | 0 tranlate2D.y | | y |
- }
- end;
-
-
-
-
-
- { Routines specific to the MPW Shell tool }
-
-
- Procedure Initialize; { Start us off somewhere }
- begin
- fPtInput.x := 100;
- fPtInput.y := 100;
- end;
-
-
-
- Function TransRotate2D(theFPoint: fPoint; theTransRot : transRot2D) : fPoint;
- { Calls Rotate2D, then Translate2D }
- begin
- TransRotate2D := Translate2D(Rotate2D(theFPoint,theTransRot),theTransRot);
- end;
-
-
-
- begin
- Initialize;
- repeat
- write('X: ');
- readln(transformInput.x);
- write('Y: ');
- readln(transformInput.y);
- write('Rotation: ');
- readln(radians);
- transformInput.rot:=round(radians * FixToIntegerConversion);
-
- fPtResult := TransRotate2D(fPtInput, transformInput);
- writeln('Output: ',fPtResult.x,fPtResult.y);
- until transformInput.rot = (999 * FixToIntegerConversion)
- end.